/*
 * @# FollowServiceImpl.java 2011-12-22 下午05:00:09
 * 
 * Copyright (C) 2010 - 2011 广州羿安信息科技有限公司
 * Guangzhou ianswer information technology co. ltd.
 * 
 * All rights reserved!
 */
package com.ianswer.px.user.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.ianswer.common.orm.PublicDao;
import com.ianswer.common.util.time.SecondsUtils;
import com.ianswer.px.user.entity.Circle;
import com.ianswer.px.user.entity.Figure;
import com.ianswer.px.user.entity.Follow;
import com.ianswer.px.user.entity.UserBaseInfo;
import com.ianswer.px.user.redis.FigureRedis;
import com.ianswer.px.user.service.FollowCircleService;
import com.ianswer.px.user.service.FollowService;

/**
 * @author pananz
 */
@Service("followService")
public class FollowServiceImpl implements FollowService {

	@Resource(name = "publicDao")
	private PublicDao publicDao;

	@Resource(name = "followCircleService")
	private FollowCircleService followCircleService;

	@Override
	public void insert(Long who, Long whom) {
		if (null == get(who, whom)) {
			Follow follow = new Follow();
			follow.setWho(who);
			follow.setWhom(whom);
			follow.setCreatedAt(SecondsUtils.seconds());
			follow.noMutual();
			if (oprMutual(who, whom, Follow.ISMUTUAL)) {
				follow.isMutual();
			}
			publicDao.insert("follow.insert", follow);

			//设置redis(关注及粉丝)
			FigureRedis.incrFollows(who);
			FigureRedis.incrFans(whom);
		}
	}

	/**
	 * 是否存在相互关注
	 * @param who
	 * @param whom
	 * @return
	 */
	private boolean oprMutual(Long who, Long whom, Long mutual) {
		boolean flag = false;
		if (get(whom, who) != null) {
			updateMutual(whom, who, mutual);
			flag = true;
		}
		return flag;
	}

	/**
	 * 修改关注状态
	 * @param who
	 * @param whom
	 */
	private void updateMutual(Long who, Long whom, Long mutual) {
		Follow follow = new Follow();
		follow.setWho(who);
		follow.setWhom(whom);
		follow.setMutual(mutual);
		publicDao.update("follow.updateMutual", follow);
	}

	@Override
	public List<UserBaseInfo> queryFans(Long whom, int skip, int max) {
		List<UserBaseInfo> fanses = new ArrayList<UserBaseInfo>();
		List<Long> fansIds = queryFansId(whom, skip, max);
		for (Long fansId : fansIds) {
			UserBaseInfo fans = UserBaseInfo.get(fansId);
			Figure figure = FigureRedis.get(fansId);
			if (null == fans) {
				continue;
			}
			fans.setFigure(figure);
			fans.setId(fansId);
			fanses.add(fans);
		}
		return fanses;
	}

	private List<Long> queryFansId(Long whom, int skip, int max) {
		return publicDao.query("follow.queryFansId", whom, skip, max);
	}

	@Override
	public List<Long> queryFansId(Long whom) {
		return publicDao.query("follow.queryFansId", whom);
	}

	@Override
	public void delete(Long who, Long whom) {
		Follow follow = new Follow();
		follow.setWho(who);
		follow.setWhom(whom);
		Follow oldFollow = get(who, whom);
		if (null != oldFollow) {
			publicDao.delete("follow.delete", follow);
			//是否去除粉丝的相互关注
			oprMutual(who, whom, Follow.NOMUTUAL);
			//删除关联信息
			followCircleService.deleteByFollowId(oldFollow.getId());
			//减少redis中的数值
			FigureRedis.decrFans(whom);
			FigureRedis.decrFollows(who);
		}
	}

	@Override
	public Follow get(Long who, Long whom) {
		Follow follow = new Follow();
		follow.setWho(who);
		follow.setWhom(whom);
		return publicDao.querySingle("follow.getByWhoAndWhom", follow);
	}

	private List<Follow> queryFollows(Long who, int skip, int max) {
		return publicDao.query("follow.queryFollows", who, skip, max);
	}

	@Override
	public List<UserBaseInfo> queryFollow(Long who, int skip, int max) {
		List<UserBaseInfo> userBaseInfos = new ArrayList<UserBaseInfo>();
		List<Follow> follows = queryFollows(who, skip, max);
		for (Follow follow : follows) {
			Long userId = follow.getWhom();
			UserBaseInfo userBaseInfo = UserBaseInfo.get(userId);
			Figure figure = FigureRedis.get(userId);
			if (null == userBaseInfo) {
				continue;
			}
			userBaseInfo.setFigure(figure);
			userBaseInfo.setId(userId);
			userBaseInfos.add(userBaseInfo);
		}
		return userBaseInfos;
	}

	/**
	 * 取得被关注人所在的圈圈列表
	 * @param circleIds
	 * @param allCircles
	 * @return
	 */
	private List<Circle> getCheckCircle(List<Long> circleIds, List<Circle> allCircles) {
		List<Circle> checkCircles = new ArrayList<Circle>();
		if (CollectionUtils.isEmpty(circleIds) || CollectionUtils.isEmpty(allCircles)) {
			return null;
		}
		for (Circle allCircle : allCircles) {
			if (circleIds.contains(allCircle.getId())) {
				checkCircles.add(allCircle);
			}
		}
		return checkCircles;
	}

	/**
	 * 取得被关注人所在的圈圈字符说明
	 * @param checkCircles
	 * @return
	 */
	private String getCircleName(List<Circle> checkCircles) {
		List<String> circleNames = new ArrayList<String>();
		if (CollectionUtils.isEmpty(checkCircles)) {
			return null;
		}
		for (Circle circle : checkCircles) {
			circleNames.add(circle.getCircleName());
		}
		return StringUtils.join(circleNames, "|");
	}

	/**
	 * 设置被关注人是否在关注人的圈圈里
	 * @param allCircles
	 * @param checkCircles
	 * @return
	 */
	private List<Circle> checkCircle(List<Circle> allCircles, List<Circle> checkCircles) {
		List<Circle> circles = new ArrayList<Circle>();
		if (CollectionUtils.isEmpty(checkCircles)) {
			circles = allCircles;
			return circles;
		}
		for (Circle circle : allCircles) {
			Circle circleBean = new Circle();
			circleBean.setId(circle.getId());
			circleBean.setCircleName(circle.getCircleName());
			//重新設定是否checked
			circleBean.setCheck(checkCircles.contains(circle));
			circles.add(circleBean);
		}
		return circles;
	}

	@Override
	public List<UserBaseInfo> queryFollow(Long who, List<Circle> circles, int skip, int max) {
		List<UserBaseInfo> userBaseInfos = new ArrayList<UserBaseInfo>();
		List<Follow> follows = queryFollows(who, skip, max);
		for (Follow follow : follows) {
			Long userId = follow.getWhom();
			UserBaseInfo userBaseInfo = UserBaseInfo.get(userId);
			if (null == userBaseInfo) {
				continue;
			}
			//设定所在圈说明
			List<Circle> checkCircles = getCheckCircle(follow.getCircleIds(), circles);
			String circleNameStr = getCircleName(checkCircles);
			userBaseInfo.setCircleNameStr(circleNameStr);
			//设置所在圈在所有圈是否checked
			List<Circle> checkAllCircles = checkCircle(circles, checkCircles);
			userBaseInfo.setCircles(checkAllCircles);

			Figure figure = FigureRedis.get(userId);
			userBaseInfo.setFigure(figure);
			userBaseInfo.setId(userId);
			userBaseInfos.add(userBaseInfo);
		}
		return userBaseInfos;
	}

	@Override
	public List<UserBaseInfo> queryMutual(Long who, List<Circle> circles, int skip, int max) {
		List<UserBaseInfo> mutuals = new ArrayList<UserBaseInfo>();
		List<Follow> mutualFollows = publicDao.query("follow.queryMutualFollow", who, skip, max);
		for (Follow follow : mutualFollows) {
			Long userId = follow.getWhom();
			UserBaseInfo mutual = UserBaseInfo.get(userId);
			if (null == mutual) {
				continue;
			}
			//设定所在圈说明
			List<Circle> checkCircles = getCheckCircle(follow.getCircleIds(), circles);
			String circleNameStr = getCircleName(checkCircles);
			mutual.setCircleNameStr(circleNameStr);
			//设置所在圈在所有圈是否checked
			List<Circle> checkAllCircles = checkCircle(circles, checkCircles);
			mutual.setCircles(checkAllCircles);

			Figure figure = FigureRedis.get(userId);
			mutual.setFigure(figure);
			mutual.setId(userId);
			mutuals.add(mutual);
		}
		return mutuals;
	}

	@Override
	public List<UserBaseInfo> queryFollowByCircle(Long circleId, Long userId, List<Circle> circles, int skip, int max) {
		Circle circle = new Circle();
		circle.setUserId(userId);
		circle.setId(circleId);
		List<Follow> follows = publicDao.query("follow.queryFollowByCircleId", circle, skip, max);

		List<UserBaseInfo> friends = new ArrayList<UserBaseInfo>();
		for (Follow follow : follows) {
			Long friendId = follow.getWhom();
			UserBaseInfo friend = UserBaseInfo.get(friendId);
			if (null == friend) {
				continue;
			}
			//设定所在圈说明
			List<Circle> checkCircles = getCheckCircle(follow.getCircleIds(), circles);
			String circleNameStr = getCircleName(checkCircles);
			friend.setCircleNameStr(circleNameStr);
			//设置所在圈在所有圈是否checked
			List<Circle> checkAllCircles = checkCircle(circles, checkCircles);
			friend.setCircles(checkAllCircles);

			friend.setFigure(FigureRedis.get(friendId));
			friend.setId(friendId);
			friends.add(friend);
		}
		return friends;
	}

	@Override
	public List<UserBaseInfo> queryCommon(Long she, Long me, int skip, int max) {
		if (StringUtils.isBlank(String.valueOf(me)) || StringUtils.isBlank(String.valueOf(me))) {
			return null;
		}
		return null;
	}

	@Override
	public void updateCircles(Follow follow) {
		publicDao.update("follow.updateCircles", follow);
	}

}
